package com.xpq.ddns;

import java.net.*;
import java.util.*;

public class IPv6Util {

    public static String getPublicIPv6Address() {
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface iface = interfaces.nextElement();
                // 过滤回环接口、未启用的接口、点对点接口和虚拟接口
                if (iface.isLoopback() || !iface.isUp() || iface.isPointToPoint() || iface.isVirtual()) {
                    continue;
                }

                Enumeration<InetAddress> addresses = iface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress addr = addresses.nextElement();
                    if (addr instanceof Inet6Address) {
                        Inet6Address ipv6Addr = (Inet6Address) addr;
                        if (isGlobalIPv6Address(ipv6Addr)) {
                            // 去除可能存在的接口作用域标识（如%eth0）
                            String hostAddress = ipv6Addr.getHostAddress();
                            int scopeIdIndex = hostAddress.indexOf('%');
                            if (scopeIdIndex != -1) {
                                hostAddress = hostAddress.substring(0, scopeIdIndex);
                            }
                            return hostAddress;
                        }
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static boolean isGlobalIPv6Address(Inet6Address addr) {
        // 全球单播地址范围：2000::/3
        byte[] ipv6Bytes = addr.getAddress();
        if ((ipv6Bytes[0] & 0xE0) != 0x20) { // 检查前3位是否为001
            return false;
        }

        // 排除本地链路地址（fe80::/10）
        if ((ipv6Bytes[0] == (byte) 0xFE) && ((ipv6Bytes[1] & 0xC0) == 0x80)) {
            return false;
        }

        // 排除唯一本地地址（fc00::/7）
        if ((ipv6Bytes[0] & 0xFE) == (byte) 0xFC) {
            return false;
        }

        return true;
    }

    public static void main(String[] args) {
        String publicIPv6 = getPublicIPv6Address();
        if (publicIPv6 != null) {
            System.out.println("Public IPv6 Address: " + publicIPv6);
        } else {
            System.out.println("No public IPv6 address found");
        }
    }
}
